﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Telerik.Web.UI;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Medianamik.Core;
using Medianamik.Core.Sugar;

namespace Medianamik.UI.Controls
{
    public class DropDownTree : BaseMedianamikControl
    {

        #region Fields

        private const int DEFAULT_WIDTH = 300;
        private const int DEFAULT_HEIGHT = 300;

        private RadComboBox _comboBox = new RadComboBox()
        {
            ID = "79EA4C34-DB89-4F94-B8A5-DB59721E2FAF"
        };

        private RadTreeView _tree = new RadTreeView();

        #endregion

        #region Events


        #endregion

        #region Properties

        public override Type TypeOfValue
        {
            get { return typeof(Guid?); }
        }

        public BasePage BasePage
        {
            get
            {
                return (BasePage)base.Page;
            }
        }

        protected int ItemCount
        {
            get
            {
                return (int)ViewState["ItemCount"];
            }
            set { ViewState["ItemCount"] = value; }
        }

        #endregion

        #region Methods

        public override object GetValue()
        {
            EnsureChildControls();

            Guid? value = null;

            if (!String.IsNullOrEmpty(_tree.SelectedValue))
                value = new Guid(_tree.SelectedValue);

            return value;
        }

        protected override void CreateControlHierarchy(bool pUseDataSource)
        {
            if (ControlInfo.Width.HasValue)
            {
                _comboBox.Width = ControlInfo.Width.Value;
            }
            else
            {
                _comboBox.Width = DEFAULT_WIDTH;
            }

            if (ControlInfo.Height.HasValue)
            {
                _comboBox.Height = ControlInfo.Height.Value;
            }
            else
            {
                _comboBox.Height = DEFAULT_HEIGHT;
            }

            RadComboBoxItem item = new RadComboBoxItem();

            HtmlGenericControl div = new HtmlGenericControl("div");
            div.Attributes.Add("onclick", "StopPropagation(event)");

            
            _tree.OnClientNodeClicking = "nodeClicking";
            _tree.NodeDataBound += new RadTreeViewEventHandler(tree_NodeDataBound);
            _tree.DataBound += new EventHandler(tree_DataBound);

            div.Controls.Add(_tree);
            item.Controls.Add(div);
            _comboBox.Items.Add(item);

            _comboBox.TextChanged += new EventHandler(_comboBox_TextChanged);
            _comboBox.AutoPostBack = true;
            _comboBox.AllowCustomText = false;
            _comboBox.EnableTextSelection = false;

            Controls.Add(_comboBox);

            if (pUseDataSource)
            {
                _tree.DataTextField = "Name";
                _tree.DataValueField = "ID";
                _tree.DataFieldID = "ID";
                _tree.DataFieldParentID = "ParentID";

                if (TreeRootNodeId.HasValue)
                {
                    Node rootNode = NodeManager.GetNode(TreeRootNodeId.Value);

                    if (rootNode != null)
                    {
                        List<HierarchicalDataItem> options = new List<HierarchicalDataItem>();

                        options.Add(new HierarchicalDataItem()
                        {
                            ID = rootNode.ID,
                            ParentID = null,
                            Name = Utility.GetFriendlyIdentifier(rootNode, MedianamikContext.Current.CurrentUICulture.Name)
                        });

                        options.AddRange(NodeManager.GetChildNodes(rootNode.ID, false, 0).
                            Select(n => new HierarchicalDataItem()
                            {
                                ID = n.ID,
                                ParentID = n.ParentID,
                                Name = Utility.GetFriendlyIdentifier(n, MedianamikContext.Current.CurrentUICulture.Name)
                            }));

                        _tree.DataSource = options;
                        _tree.DataBind();
                    }
                }
                else
                {
                    _tree.DataSource = Options.Select(n => new HierarchicalDataItem()
                    {
                        ID = n.NodeId,
                        ParentID = GetFixedParentId(n, Options),
                        Name = n.Text
                    });
                    _tree.DataBind();
                }
            }
        }

        void _comboBox_TextChanged(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }

        void tree_DataBound(object sender, EventArgs e)
        {
            Guid? id = null;
            if(DataSource != null && StringHelper.IsGuid(DataSource.ToString(), ref id))
            {
                RadTreeNode node = ((RadTreeView)sender).FindNodeByValue(DataSource.ToString());
                node.Selected = true;
                node.ExpandParentNodes();
                _comboBox.Items[0].Text = node.Text;
                _comboBox.Items[0].Value = node.Value;
            }
        }

        void tree_NodeDataBound(object sender, RadTreeNodeEventArgs e)
        {
            if (!Options.Contains(new Guid(e.Node.Value)))
            {
                e.Node.Category = "Disabled";
                e.Node.CssClass += " rtDisabled";
            }
        }

        private Guid? GetFixedParentId(RelationOption n, RelationOptionCollection Options)
        {
            if (n.ParentNodeId.HasValue)
            {
                RelationOption option = Options.SingleOrDefault(o => o.NodeId.Equals(n.ParentNodeId.Value));

                if (option == null)
                    return null;
                else
                    return option.NodeId;
            }

            return n.ParentNodeId;
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            string script = String.Concat("function nodeClicking(sender, args) {\n",
                " var comboBox = $find('" + _comboBox.ClientID + "');\n",
                " var node = args.get_node();\n",
                " alert(node.get_value() == comboBox.get_value());",
                "if (node.get_category() == \"Disabled\" || node.get_value() == comboBox.get_value()) {\n",
                "args.set_cancel(true);\n",
                "}\n",
                "else {\n",
                " comboBox.set_text(node.get_text());\n",
                " comboBox.set_value(node.get_value());\n",
                " comboBox.hideDropDown();\n",
                " }}\n",
                " function StopPropagation(e) {\n",
                "if(typeof(e) == 'undefined' || !e) {\n",
                " e = window.event;\n",
                "}\n",
                "e.cancelBubble = true;\n",
                " }\n");


            ScriptManager.RegisterClientScriptBlock(this, typeof(TreeView), "DropDownTreeScript",
                    script, true);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            //Hack pour synchroniser les valeurs du treeview et du combobox après un postback
            if (Page.IsPostBack && _tree.SelectedNode != null)
            {
                _comboBox.SelectedValue = _tree.SelectedNode.Value;
                _comboBox.Text = _tree.SelectedNode.Text;
            }

            BeginRenderControl(writer);
            _comboBox.RenderControl(writer);
            EndRenderControl(writer);
        }

        #endregion

    }
}
